package com.zjuee.base.utils;


import com.zjuee.base.enums.FileTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.system.ApplicationHome;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;

/**
 * 文件上传下载相关工具类
 *
 * @author wu liang
 * @since 1.0
 */
@Slf4j
public class FileUtil {


    //允许上传的图片格式
    //public static final String ALL_IMAGE_EXTS = "jpg,jpeg,png,gif,psd,bmp";
    //所有允许上传的文件格式
    //public static final String ALL_FILE_EXTS = "jpg,jpeg,png,gif,psd,bmp,bpmn,doc,docx,xls,xlsx,ppt,pptx,pdf,zip,rar,7z,gz,tar,txt,xml,iso,mp4,rm,flv,wmv,asf,mov,mpg,mpeg,avi,mp3,wav,mid,midi,ra,wma";
    public static final String ALL_FILE_EXTS = "jpg,jpeg,png,gif,doc,docx,pdf,rtf,wps";
    //允许文件大小,100M
    public static final int ALLOW_FILE_SIZE = 100 * 1024 * 1024;
    // 非法路径符，为了安全，必须要校验
    private static final String ILLEGAL_PATH = ".." + File.separator;

    //将允许上传的文件格式转为set集合，提高比较性能
    private static final Set<String> fileSuffixSet = new HashSet<>();
    static {
        String[] split = ALL_FILE_EXTS.split(",");
        CollectionUtils.addAll(fileSuffixSet, split);
    }

    /**
     * 验证文件格式-真实类型
     */
    public static boolean CheckFileType(InputStream inputStream) throws IOException {
        boolean isVaild = false;


        byte[] buffer = new byte[10];
        inputStream.read(buffer);


        //获取当前文件的真实类型
        String fileType = getTrueFileType(bytesToHexFileTypeString(buffer));

        //指定文件类型中是否匹配当前文件类型
        if (fileType != null) {
            isVaild = true;
        }
        return isVaild;
    }

    /**
     * 验证文件格式-真实类型
     */
    public static boolean CheckFileType(InputStream inputStream, String fileExt) throws IOException {

        byte[] buffer = new byte[10];
        inputStream.read(buffer);

        //获取当前文件的真实类型
        return checkSuffix(fileExt, bytesToHexFileTypeString(buffer));

    }

    private static String getTrueFileType(String s) {
        for (FileTypeEnum fileTypeEnum : FileTypeEnum.values()) {
            if (s.startsWith(fileTypeEnum.getValue())) {
                return fileTypeEnum.toString();
            }
        }
        return null;
    }

    private static String bytesToHexFileTypeString(byte[] buffer) {
        StringBuilder hexFileTypeStr = new StringBuilder();
        for (byte b : buffer) {
            String hexString = Integer.toHexString(b & 0xFF);
            if (hexString.length() < 2) {
                hexFileTypeStr.append("0");
            }
            hexFileTypeStr.append(hexString);
        }
        return hexFileTypeStr.toString();
    }


    /**
     * 格式化文件大小,返回(KB,MB,GB格式)
     */
    public static String getFormatSize(long size) {
        long kiloByte = size / 1024;
        if (kiloByte < 1) {
            return size + "Byte(s)";
        }

        long megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
        }

        long gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }

        long teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }


    /**
     * 校验文件是否为被允许的文件后缀
     */
    public static boolean checkSuffix(String suffix) {
        if (fileSuffixSet.isEmpty() || StringUtils.isBlank(suffix)){
            return false;
        }
        return fileSuffixSet.contains(suffix.toLowerCase());
    }

    /**
     * 根据允许格式，校验文件是否为被允许的文件后缀
     */
    public static boolean checkSuffix(String fileExt, String suffix) {
        if (fileExt.isEmpty() || StringUtils.isBlank(suffix)){
            return false;
        }
        return fileExt.toLowerCase().contains(suffix.toLowerCase());
    }

    /**
     * 校验后缀是否为图片
     * @param suffix
     * @return
     */
    public static boolean isImage(String suffix) {
        if (StringUtils.isBlank(suffix))
            return false;
        return suffix.matches("^(?i)(jpg|jpeg|png|gif|bmp|psd|pdf)");
    }

    /**
     * 获取文件扩展名(返回小写)
     * @param fileName 文件名
     * @return 例如：test.jpg  返回：  .jpg
     */
    public static String getFileExtension(String fileName) {
        if ((fileName == null) || (fileName.lastIndexOf(".") == -1)
                || (fileName.lastIndexOf(".") == fileName.length() - 1)) {
            return null;
        }
        return StringUtils.lowerCase(fileName.substring(fileName.lastIndexOf(".")));
    }

    /**
     * 获取当前项目所在目录的绝对路径
     */
    public static String getWebRootPath(){
        ApplicationHome home = new ApplicationHome();
        return home.getDir().getAbsolutePath()+File.separator;
    }

}
